iT邦幫忙

2021 iThome 鐵人賽

DAY 24
0
Software Development

From State Machine to XState系列 第 24

Day24 - 在 XState 中的階層式狀態 Hierarchical States

  • 分享至 

  • xImage
  •  

還記得我們在 Day 14 的例子嗎?

https://ithelp.ithome.com.tw/upload/images/20210927/20130721esiomcqiFn.png

https://ithelp.ithome.com.tw/upload/images/20210929/20130721UvlbWhoZpj.png

這是一個比較符合現實情境的 Input 元件狀態,只有當 input content 有改變時, valid / invalid 的情境才是有意義的。也就是說 changed 這個父階層底下會有 valid / invalid 的兩種「狀態」及改變狀態的「事件」。

1. 如何在 XState 描述 Hierarchical States

以下是 2 個 一般的 FSM

  // door machine config
  const doorMachinceConfig = {
    id: "door",
    initial: "關著",
    states: {
      關著: {
        on: { 開門: "開了" }
      },
      開了: {
        on: {
          關門: { target: "關著" }
        }
      }
    }
  };
  
 // some FSM config
 const someFSMConfig = {
    id: "myId",
    initial: "state1",
    states: {
      state1: {
        on: {
          event1: { target: "state2" }
        }
      },
      state2: {
        on: {
          event2: { target: "state1" }
        }
      }
    }
  };
  

我們說階層狀態,也就是某個狀態底下有子狀態、子狀態機的意思!
那就是把某個狀態機的定義丟進另一個狀態機之下的「特定狀態後」,就可以完成了!

比方說,someFSMConfigstate2 是個階層狀態,底下是一個 doorMachine,那...

  // door machine config
  const doorMachinceConfig = {
    id: "door",
    initial: "關著",
    states: {
      關著: {
        on: { 開門: "開了" }
      },
      開了: {
        on: {
          關門: { target: "關著" }
        }
      }
    }
  };
  
 // some FSM config
 const someFSMConfig = {
    id: "myId",
    initial: "state1",
    states: {
      state1: {
        on: {
          event1: { target: "state2" }
        }
      },
      state2: {
        on: {
          event2: { target: "state1" }
-       }
+       },
+       ...doorMachinceConfig,
      }
    }
  };
  

只要把這個子狀態機的定義丟進父狀態底下即可!
https://ithelp.ithome.com.tw/upload/images/20211009/20130721o35TXe1xOx.png

範例可參考Example Demo


2. 完成需求

const inputMachine = Machine({
  id: "inputMachine_v2",
  type: "parallel",

  states: {
    enabled: {
      initial: "enabled",
      states: {
        disabled: {
          on: {
            ENABLE: { target: "enabled" },
          },
        },
        enabled: {
          on: {
            DISABLE: { target: "disabled" },
          },
        },
      },
    },
    changed: {
      initial: "unchanged",
      states: {
        unchanged: {
          on: {
            CHANGE: { target: "changed" },
          },
        },
        changed: {
          initial: "valid",
          states: {
            invalid: {
              on: {
                VALIDATE: { target: "valid" },
              },
            },
            valid: {
              on: {
                INVALIDATE: { target: "invalid" },
              },
            },
          },
        },
      },
    },
  },
});

DEMO Visualizer

https://ithelp.ithome.com.tw/upload/images/20211009/20130721n0YAXCb28a.png

這兩天的描述都比較倉促、比較短,如果有哪裡有疑問或是建議補充的,也歡迎大家指教一下!

參考資料

https://xstate.js.org/docs/guides/hierarchical.html


上一篇
Day23 - 在 XState 中的平行式狀態 Parallel States
下一篇
Day25 - 保護你的狀態轉移,在 XState 中使用 Guard Transition
系列文
From State Machine to XState31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言